/*  Copyright (C) 2008  Alexander Blyzniuchenko (BlezAlex)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Reflection;
using System.Xml.Serialization;

namespace MediaDC
{
    public class Config
    {
        #region "utility section"

        private const string _configFileName = "MediaDC.Settings.xml";
        private static Config _instance;
        private static readonly XmlSerializer _serializer = new XmlSerializer(typeof(Config));
        private static readonly object _syncObject = new object();

        private Config()
        { }

        public void Save()
        {
            using (FileStream configFile = File.Create(_configFileName))
            {
                _serializer.Serialize(configFile, Instance);
            }
        }

        public static Config Instance
        {
            get
            {
                lock (_syncObject)
                {
                    if (_instance == null)
                    {
                        try
                        {
                            using (FileStream configFile = File.OpenRead(_configFileName))
                            {
                                _instance = (Config)_serializer.Deserialize(configFile);
                            }
                        }
                        catch
                        {
                            _instance = new Config();
                        }

                        Assembly me = Assembly.GetExecutingAssembly();
                        using (Stream s = me.GetManifestResourceStream("MediaDC.Default.Settings.xml"))
                        {
                            try
                            {
                                Config defaultConfig = (Config)_serializer.Deserialize(s);

                                Type type = typeof(Config);
                                FieldInfo[] fi = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
                                foreach (FieldInfo info in fi)
                                {
                                    object value = info.GetValue(_instance);
                                    object defaultValue = info.GetValue(defaultConfig);

                                    if ((value == null && defaultValue != null) ||
                                         (value is IList && ((IList)value).Count == 0)
                                        )
                                        info.SetValue(_instance, defaultValue);
                                }

                            }
                            catch
                            { }
                        }
                    }
                    return _instance;
                }
            }
        }

        #endregion

        #region settings

        private string _nickName = "MediaDC.Net";
        public string NickName
        {
            get { return _nickName; }
            set { _nickName = value; }
        }

        private string _localIP = GetFirstLocalIP();
        [Description("Put here your ip on this machine")]
        [DisplayName("Local IP")]
        public string IP
        {
            get { return _localIP; }
            set { _localIP = value; }
        }

        private readonly List<HubRegistration> _registredHubUrls = new List<HubRegistration>();
        public List<HubRegistration> RegistredHubUrls
        {
            get { return _registredHubUrls; }
        }

        private string _tempFolderPath = Path.GetTempPath();
        [EditorAttribute(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(System.Drawing.Design.UITypeEditor))]
        public string TempFolderPath
        {
            get { return _tempFolderPath; }
            set { _tempFolderPath = value; }
        }


        private int _webServerPort = 8080;
        [Description("Do not edit if you are not absolutely sure about what you are doing.")]
        [DisplayName("WebServerPort")]
        public int WebServerPort
        {
            get { return _webServerPort; }
            set { _webServerPort = value; }
        }

        public string Version
        {
            get { return Assembly.GetExecutingAssembly().GetName().Version.ToString(); }
        }


    	private string _lastNotifiedVersion;
		public string LastNotifiedVersion
		{
			get
			{
				return string.IsNullOrEmpty(_lastNotifiedVersion) ? Version : _lastNotifiedVersion;
			} 
			set
			{
				_lastNotifiedVersion = value;
			}
		}

        private readonly List<PreviewAssociation> _previewAssociations = new List<PreviewAssociation>();
        [Description("Here you can set preview mode and preview programm for specific file type. If not specified, temp file and windows associations will be used.")]
        [DisplayName("Preview Associations")]
        public List<PreviewAssociation> PreviewAssociations
        {
            get { return _previewAssociations; }
        }


        #endregion

        private static string GetFirstLocalIP()
        {
            IPAddress[] address = Dns.GetHostAddresses(Dns.GetHostName());
            if (address.Length > 0)
                return address[0].ToString();
            return "127.0.0.1";
        }
    }
}